﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Windows.Forms;
using ValidationEngine.Commons;
using ValidationEngine.Core;
using ValidationEngine.Commons.Enums;

namespace ValidationEngine.Tools
{
    /// <summary>
    /// Implements IValidationMgr interface
    /// </summary>
    public class ValidationProvider : IValidationProvider
    {
        #region Members
        private IViewMgr _viewMgr;
        private IValidatorsMgr _validatorsMgr;
        private IBindableView _view;
        private IModelMgr _modelMgr;
        
        #endregion

        #region Properties
        public IBindableView View
        {
            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("View");
                }

                _view = value;
                try
                {
                    _viewMgr.ScanControls(_view);
                    _modelMgr.ModelSource = _view.Source;
                }
                catch (EngineCoreExcception)
                {
                    throw;
                }
            }
        }

        internal IViewMgr ViewMgr
        {
            get
            {

                return _viewMgr;
            }
            set
            {
                if (null == _viewMgr)
                {
                    throw new ArgumentNullException("ViewMgr");
                }
                _viewMgr = value;
            }
        }

        internal IValidatorsMgr ValidatorsMgr
        {
            get { return _validatorsMgr; }
            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("ValidatorsMgr");
                }
                _validatorsMgr = value;
            }
        }

        public IValidateableModel Model
        {
            set
            {
                if (null == value)
                {
                    throw new ArgumentNullException("model");
                }
                _modelMgr.Model = value;
            }
        }

        public bool IsModelValid
        {
            get { return _modelMgr.Model == null ? false : _modelMgr.Model.IsValid; }
        }
        #endregion

        #region IValidationMgr
        public void RegisterValidator<TModel>(IValidator validator)
        {
            _validatorsMgr.RegisterValidator(typeof(TModel), validator);
        }

        public IValidateableModel ValidateModel(RuleApplingContext ctx = RuleApplingContext.Always)
        {
            _modelMgr.RevalidateModel(ctx);
            return _modelMgr.Model;
        }

        public IValidateableModel ValidateModel(IValidateableModel model, RuleApplingContext ctx = RuleApplingContext.Always)
        {
            if (null == model)
            {
                throw new ArgumentNullException("model");
            }
            _modelMgr.Model = model;
            _modelMgr.RevalidateModel(ctx);
            return _modelMgr.Model;
        }

        public IValidator GetValidator<ModelType>() where ModelType : IValidateableModel
        {
            return _validatorsMgr.GetValidatorForType(typeof(ModelType));
        } 
        #endregion

        #region Ctor
        public ValidationProvider()
        {
            this._viewMgr = new ViewMgr();
            this._validatorsMgr = new ValidatorsMgr();
            this._modelMgr = new ModelMgr(this);
        } 
        #endregion


        
    }
}